﻿namespace MSHelpMe.ViewModels
{
    using System;
    using System.ComponentModel;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Xml.Linq;
    using MSHelpMe.BingService;

    public class ItemViewModel : INotifyPropertyChanged
    {
        public static Dictionary<string, string> icons = new Dictionary<string, string>();

        static ItemViewModel()
        {
            icons.Add("1", "Images\\kb.png");
            icons.Add("2", "Images\\kb.png");
            icons.Add("3", "Images\\kb.png");
            icons.Add("4", "Images\\kb.png");
            icons.Add("5", "Images\\msdn.png");
            icons.Add("6", "Images\\technet.png");
            icons.Add("25", "Images\\office.png");
            icons.Add("26", "Images\\ie2.png");
            icons.Add("27", "Images\\windows.png");
            icons.Add("28", "Images\\windows.png");
            icons.Add("29", "Images\\answers.png");
            icons.Add("30", "Images\\windowsphone.png");
            icons.Add("31", "Images\\xbox.png");
            icons.Add("36", "Images\\office.png");
            icons.Add("37", "Images\\windows.png");

            icons.Add("kb", "Images\\kb.png");
            icons.Add("msdn", "Images\\msdn.png");
            icons.Add("technet", "Images\\technet.png");
            icons.Add("office", "Images\\office.png");
            icons.Add("ie", "Images\\ie2.png");
            icons.Add("windows", "Images\\windows.png");
            icons.Add("answers", "Images\\answers.png");
            icons.Add("wp", "Images\\windowsphone.png");
            icons.Add("xbox", "Images\\xbox.png");
        }

        private string title;

        /// <summary>
        /// Title of the item.
        /// </summary>
        public string Title
        {
            get
            {
                return this.title;
            }
            set
            {
                this.title = value;
                NotifyPropertyChanged("Title");
            }
        }

        private string summary;

        /// <summary>
        /// Summary of the item.
        /// </summary>
        public string Summary
        {
            get
            {
                return this.summary;
            }
            set
            {
                this.summary = value;
                NotifyPropertyChanged("Summary");
            }
        }

        private string assetType;

        /// <summary>
        /// Asset type of the item. For examples: KB, MSDN
        /// </summary>
        public string AssetType
        {
            get
            {
                return this.assetType;
            }
            set
            {
                this.assetType = value;
                NotifyPropertyChanged("AssetType");
            }
        }

        private string lastModifiedTime;

        /// <summary>
        /// LastModifiedTime of the item.
        /// </summary>
        public string LastModifiedTime
        {
            get
            {
                return this.lastModifiedTime;
            }
            set
            {
                this.lastModifiedTime = value;
                NotifyPropertyChanged("LastModifiedTime");
            }
        }

        private string uri;

        /// <summary>
        /// Uri of the item.
        /// </summary>
        public string Uri
        {
            get
            {
                return this.uri;
            }
            set
            {
                this.uri = value;
                NotifyPropertyChanged("Uri");
            }
        }

        /// <summary>
        /// Indicates if the item has been flagged.
        /// </summary>
        public bool Flagged
        {
            get
            {
                return App.ViewModel.HasFlagged(this);
            }
        }

        public string FlaggedIcon
        {
            get
            {
                return this.Flagged ? "Images\\star_2.png" : "Images\\star_1.png";
            }
        }

        public string Icon
        {
            get
            {
                return icons.ContainsKey(this.AssetType) ? icons[this.AssetType] : string.Empty;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public void NotifyFlagChanged()
        {
            NotifyPropertyChanged("Flagged");
            NotifyPropertyChanged("FlaggedIcon");
        }

        public string ToXml()
        {
            var node = new XElement("result");
            node.SetElementValue("title", this.Title);
            node.SetElementValue("summary", this.Summary);
            node.SetElementValue("assetType", this.AssetType);
            node.SetAttributeValue("uri", this.Uri);
            node.SetAttributeValue("modified", this.LastModifiedTime);

            return node.ToString();
        }

        public static ItemViewModel Create(WebResult bingItem)
        {
            var item = new ItemViewModel
                           {
                               Title = bingItem.Title,
                               Summary = bingItem.Description,
                               Uri = bingItem.Url,
                               AssetType = DetectAssetType(bingItem.Url.ToLowerInvariant()),
                               LastModifiedTime = GetLastModTime(bingItem.DateTime)
                           };

            return item;
        }

        private static string GetLastModTime(string time)
        {
            var modtime = DateTime.Now;

            if (!string.IsNullOrWhiteSpace(time))
            {
                DateTime.TryParse(time, out modtime);
            }

            return modtime.ToString(CultureInfo.InvariantCulture);
        }

        private static string DetectAssetType(string url)
        {
            if (url.Contains("/kb/"))
            {
                return "kb";
            }

            if (url.Contains("msdn"))
            {
                return "msdn";
            }

            if (url.Contains("technet"))
            {
                return "technet";
            }

            if (url.Contains("office"))
            {
                return "office";
            }

            if (url.Contains("/ie/"))
            {
                return "ie";
            }

            if (url.Contains("windows") || url.Contains("windowsteamblog"))
            {
                return "windows";
            }

            if (url.Contains("windowsphone") || url.Contains("zune"))
            {
                return "wp";
            }

            if (url.Contains("xbox"))
            {
                return "xbox";
            }

            if (url.Contains("answers"))
            {
                return "answers";
            }
            
            return string.Empty;
        }

        public static ItemViewModel ParseResultElement(XElement element)
        {
            var item = new ItemViewModel();
            var e = element.Element("title");

            if (e != null)
            {
                item.Title = e.Value;
            }

            e = element.Element("summary");

            if (e != null)
            {
                item.Summary = e.Value;
            }

            e = element.Element("assetType");

            if (e != null)
            {
                item.assetType = e.Value;
            }

            var a = element.Attribute("uri");

            if (a != null)
            {
                item.Uri = a.Value;
            }

            a = element.Attribute("modified");

            if (a != null)
            {
                item.LastModifiedTime = GetLastModTime(a.Value);
            }

            return item;
        }
    }
}